<!DOCTYPE html>
<html>

<head>
  <title>Quarkus - Connecting to an Elasticsearch cluster</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/guides/elasticsearch" />
  <meta property="og:title" content="Quarkus - Connecting to an Elasticsearch cluster" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/guides/elasticsearch">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="guides">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="active">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="guide">
  <div class="width-12-12">
    <h1 class="text-caps">Quarkus - Connecting to an Elasticsearch cluster</h1>
    <div class="hide-mobile toc"><ul class="sectlevel1">
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#architecture">Architecture</a></li>
<li><a href="#solution">Solution</a></li>
<li><a href="#creating-the-maven-project">Creating the Maven project</a></li>
<li><a href="#creating-your-first-json-rest-service">Creating your first JSON REST service</a></li>
<li><a href="#configuring-elasticsearch">Configuring Elasticsearch</a></li>
<li><a href="#running-an-elasticsearch-cluster">Running an Elasticsearch cluster</a></li>
<li><a href="#creating-a-frontend">Creating a frontend</a></li>
<li><a href="#using-the-high-level-rest-client">Using the High Level REST Client</a></li>
<li><a href="#hibernate-search-elasticsearch">Hibernate Search Elasticsearch</a></li>
<li><a href="#cluster-health-check">Cluster Health Check</a></li>
<li><a href="#building-a-native-executable">Building a native executable</a></li>
<li><a href="#conclusion">Conclusion</a></li>
<li><a href="#configuration-reference">Configuration Reference</a></li>
</ul></div>
    <div>
      <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Elasticsearch is a well known full text search engine and NoSQL datastore.</p>
</div>
<div class="paragraph">
<p>In this guide, we will see how you can get your REST services to use an Elasticsearch cluster.</p>
</div>
<div class="paragraph">
<p>Quarkus provides two ways of accessing Elasticsearch: via the lower level <code>RestClient</code> or via the <code>RestHighLevelClient</code> we will call them
the low level and the high level clients.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>This technology is considered preview.</p>
</div>
<div class="paragraph">
<p>In <em>preview</em>, backward compatibility and presence in the ecosystem is not guaranteed.
Specific improvements might require to change configuration or APIs and plans to become <em>stable</em> are under way.
Feedback is welcome on our <a href="https://groups.google.com/d/forum/quarkus-dev">mailing list</a> or as issues in our <a href="https://github.com/quarkusio/quarkus/issues">GitHub issue tracker</a>.</p>
</div>
<div class="paragraph">
<p>For a full list of possible extension statuses, check our <a href="https://quarkus.io/faq/#extension-status">FAQ entry</a>.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="prerequisites"><a class="anchor" href="#prerequisites"></a>Prerequisites</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To complete this guide, you need:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>less than 15 minutes</p>
</li>
<li>
<p>an IDE</p>
</li>
<li>
<p>JDK 1.8+ installed with <code>JAVA_HOME</code> configured appropriately</p>
</li>
<li>
<p>Apache Maven 3.6.2+</p>
</li>
<li>
<p>Elasticsearch installed or Docker installed</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="architecture"><a class="anchor" href="#architecture"></a>Architecture</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The application built in this guide is quite simple: the user can add elements in a list using a form and the list is updated.</p>
</div>
<div class="paragraph">
<p>All the information between the browser and the server is formatted as JSON.</p>
</div>
<div class="paragraph">
<p>The elements are stored in Elasticsearch.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="solution"><a class="anchor" href="#solution"></a>Solution</h2>
<div class="sectionbody">
<div class="paragraph">
<p>We recommend that you follow the instructions in the next sections and create the application step by step.
However, you can go right to the completed example.</p>
</div>
<div class="paragraph">
<p>Clone the Git repository: <code>git clone <a href="https://github.com/quarkusio/quarkus-quickstarts.git" class="bare">https://github.com/quarkusio/quarkus-quickstarts.git</a></code>, or download an <a href="https://github.com/quarkusio/quarkus-quickstarts/archive/master.zip">archive</a>.</p>
</div>
<div class="paragraph">
<p>The solution for the low level client is located in the <code>elasticsearch-rest-client-quickstart</code> <a href="https://github.com/quarkusio/quarkus-quickstarts/tree/master/elasticsearch-rest-client-quickstart">directory</a>.</p>
</div>
<div class="paragraph">
<p>The solution for the high level client is located in the <code>elasticsearch-rest-high-level-client-quickstart</code> <a href="https://github.com/quarkusio/quarkus-quickstarts/tree/master/elasticsearch-rest-high-level-client-quickstart">directory</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="creating-the-maven-project"><a class="anchor" href="#creating-the-maven-project"></a>Creating the Maven project</h2>
<div class="sectionbody">
<div class="paragraph">
<p>First, we need a new project. Create a new project with the following command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">mvn io.quarkus:quarkus-maven-plugin:1.7.0.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=elasticsearch-quickstart \
    -DclassName="org.acme.elasticsearch.FruitResource" \
    -Dpath="/fruits" \
    -Dextensions="resteasy-jackson,elasticsearch-rest-client"
cd elasticsearch-quickstart</code></pre>
</div>
</div>
<div class="paragraph">
<p>This command generates a Maven structure importing the RESTEasy/JAX-RS, Jackson, and the Elasticsearch low level client extensions.
After this, the <code>quarkus-elasticsearch-rest-client</code> extension has been added to your <code>pom.xml</code>.</p>
</div>
<div class="paragraph">
<p>If you want to use the high level client instead, replace the <code>elasticsearch-rest-client</code> extension by the <code>elasticsearch-rest-high-level-client</code> extension.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>We use the <code>resteasy-jackson</code> extension here and not the JSON-B variant because we will use the Vert.x <code>JsonObject</code> helper
to serialize/deserialize our objects to/from Elasticsearch and it uses Jackson under the hood.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If you don’t want to generate a new project, add the following dependencies to your pom.xml.</p>
</div>
<div class="paragraph">
<p>For the Elasticsearch low level client, add:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
    &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
    &lt;artifactId&gt;quarkus-elasticsearch-rest-client&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>For the Elasticsearch high level client, add:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
    &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
    &lt;artifactId&gt;quarkus-elasticsearch-rest-high-level-client&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="creating-your-first-json-rest-service"><a class="anchor" href="#creating-your-first-json-rest-service"></a>Creating your first JSON REST service</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In this example, we will create an application to manage a list of fruits.</p>
</div>
<div class="paragraph">
<p>First, let&#8217;s create the <code>Fruit</code> bean as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.elasticsearch;

public class Fruit {
    public String id;
    public String name;
    public String color;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Nothing fancy. One important thing to note is that having a default constructor is required by the JSON serialization layer.</p>
</div>
<div class="paragraph">
<p>Now create a <code>org.acme.elasticsearch.FruitService</code> that will be the business layer of our application and store/load the fruits from the Elasticsearch instance.
Here we use the low level client, if you want to use the high level client instead follow the instructions in the <a href="#using-the-high-level-rest-client">Using the High Level REST Client</a> paragraph instead.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.elasticsearch;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;

import org.apache.http.util.EntityUtils;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;

import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

@ApplicationScoped
public class FruitService {
    @Inject
    RestClient restClient; <i class="conum" data-value="1"></i><b>(1)</b>

    public void index(Fruit fruit) throws IOException {
        Request request = new Request(
                "PUT",
                "/fruits/_doc/" + fruit.id); <i class="conum" data-value="2"></i><b>(2)</b>
        request.setJsonEntity(JsonObject.mapFrom(fruit).toString()); <i class="conum" data-value="3"></i><b>(3)</b>
        restClient.performRequest(request); <i class="conum" data-value="4"></i><b>(4)</b>
    }

    public Fruit get(String id) throws IOException {
        Request request = new Request(
                "GET",
                "/fruits/_doc/" + id);
        Response response = restClient.performRequest(request);
        String responseBody = EntityUtils.toString(response.getEntity());
        JsonObject json = new JsonObject(responseBody); <i class="conum" data-value="5"></i><b>(5)</b>
        return json.getJsonObject("_source").mapTo(Fruit.class);
    }

    public List&lt;Fruit&gt; searchByColor(String color) throws IOException {
        return search("color", color);
    }

    public List&lt;Fruit&gt; searchByName(String name) throws IOException {
        return search("name", name);
    }

    private List&lt;Fruit&gt; search(String term, String match) throws IOException {
        Request request = new Request(
                "GET",
                "/fruits/_search");
        //construct a JSON query like {"query": {"match": {"&lt;term&gt;": "&lt;match"}}
        JsonObject termJson = new JsonObject().put(term, match);
        JsonObject matchJson = new JsonObject().put("match", termJson);
        JsonObject queryJson = new JsonObject().put("query", matchJson);
        request.setJsonEntity(queryJson.encode());
        Response response = restClient.performRequest(request);
        String responseBody = EntityUtils.toString(response.getEntity());

        JsonObject json = new JsonObject(responseBody);
        JsonArray hits = json.getJsonObject("hits").getJsonArray("hits");
        List&lt;Fruit&gt; results = new ArrayList&lt;&gt;(hits.size());
        for (int i = 0; i &lt; hits.size(); i++) {
            JsonObject hit = hits.getJsonObject(i);
            Fruit fruit = hit.getJsonObject("_source").mapTo(Fruit.class);
            results.add(fruit);
        }
        return results;
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this example you can note the following:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>We inject an Elasticsearch low level <code>RestClient</code> into our service.</p>
</li>
<li>
<p>We create an Elasticsearch request.</p>
</li>
<li>
<p>We use Vert.x <code>JsonObject</code> to serialize the object before sending it to Elasticsearch, you can use whatever you want to serialize to JSON.</p>
</li>
<li>
<p>We send the request (indexing request here) to Elasticsearch.</p>
</li>
<li>
<p>In order to deserialize the object from Elasticsearch, we again use Vert.x <code>JsonObject</code>.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Now, edit the <code>org.acme.elasticsearch.FruitResource</code> class as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@Path("/fruits")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class FruitResource {
    @Inject
    FruitService fruitService;

    @POST
    public Response index(Fruit fruit) throws IOException {
        if (fruit.id == null) {
            fruit.id = UUID.randomUUID().toString();
        }
        fruitService.index(fruit);
        return Response.created(URI.create("/fruits/" + fruit.id)).build();
    }

    @GET
    @Path("/{id}")
    public Fruit get(@PathParam("id") String id) throws IOException {
        return fruitService.get(id);
    }

    @GET
    @Path("/search")
    public List&lt;Fruit&gt; search(@QueryParam("name") String name, @QueryParam("color") String color) throws IOException {
        if (name != null) {
            return fruitService.searchByName(name);
        } else if (color != null) {
            return fruitService.searchByColor(color);
        } else {
            throw new BadRequestException("Should provide name or color query parameter");
        }
    }

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The implementation is pretty straightforward and you just need to define your endpoints using the JAX-RS annotations and use the <code>FruitService</code> to list/add new fruits.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="configuring-elasticsearch"><a class="anchor" href="#configuring-elasticsearch"></a>Configuring Elasticsearch</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The main property to configure is the URL to connect to the Elasticsearch cluster.</p>
</div>
<div class="paragraph">
<p>A sample configuration should look like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="properties" class="language-properties hljs"># configure the Elasticsearch client for a cluster of two nodes
quarkus.elasticsearch.hosts = elasticsearch1:9200,elasticsearch2:9200</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this example, we are using a single instance running on localhost:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="properties" class="language-properties hljs"># configure the Elasticsearch client for a single instance on localhost
quarkus.elasticsearch.hosts = localhost:9200</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you need a more advanced configuration, you can find the comprehensive list of supported configuration properties at the end of this guide.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="running-an-elasticsearch-cluster"><a class="anchor" href="#running-an-elasticsearch-cluster"></a>Running an Elasticsearch cluster</h2>
<div class="sectionbody">
<div class="paragraph">
<p>As by default, the Elasticsearch client is configured to access a local Elasticsearch cluster on port 9200 (the default Elasticsearch port),
if you have a local running instance on this port, there is nothing more to do before being able to test it!</p>
</div>
<div class="paragraph">
<p>If you want to use Docker to run an Elasticsearch instance, you can use the following command to launch one:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">docker run --name elasticsearch  -e "discovery.type=single-node" -e "ES_JAVA_OPTS=-Xms512m -Xmx512m"\
       --rm -p 9200:9200 docker.elastic.co/elasticsearch/elasticsearch-oss:{elasticsearch-version}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="creating-a-frontend"><a class="anchor" href="#creating-a-frontend"></a>Creating a frontend</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Now let&#8217;s add a simple web page to interact with our <code>FruitResource</code>.
Quarkus automatically serves static resources located under the <code>META-INF/resources</code> directory.
In the <code>src/main/resources/META-INF/resources</code> directory, add a <code>fruits.html</code> file with the content from this <a href="https://github.com/quarkusio/quarkus-quickstarts/blob/master/elasticsearch-low-level-client-quickstart/src/main/resources/META-INF/resources/fruits.html">fruits.html</a> file in it.</p>
</div>
<div class="paragraph">
<p>You can now interact with your REST service:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>start Quarkus with <code>./mvnw quarkus:dev</code></p>
</li>
<li>
<p>open a browser to <code><a href="http://localhost:8080/fruits.html" class="bare">http://localhost:8080/fruits.html</a></code></p>
</li>
<li>
<p>add new fruits to the list via the 'Add fruit' form</p>
</li>
<li>
<p>search for fruits by name or color via the 'Search Fruit' form</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="using-the-high-level-rest-client"><a class="anchor" href="#using-the-high-level-rest-client"></a>Using the High Level REST Client</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Quarkus provides support for the Elasticsearch High Level REST Client but keep in mind that it comes with some caveats:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>It drags a lot of dependencies - especially Lucene -, which doesn&#8217;t fit well with Quarkus philosophy. The Elasticsearch team is aware of this issue and it might improve sometime in the future.</p>
</li>
<li>
<p>It is tied to a certain version of the Elasticsearch server: you cannot use a High Level REST Client version 7 to access a server version 6.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Here is a version of the <code>FruitService</code> using the high level client instead of the low level one:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;

import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;

import io.vertx.core.json.JsonObject;

@ApplicationScoped
public class FruitService {
    @Inject
    RestHighLevelClient restHighLevelClient; <i class="conum" data-value="1"></i><b>(1)</b>

    public void index(Fruit fruit) throws IOException {
        IndexRequest request = new IndexRequest("fruits"); <i class="conum" data-value="2"></i><b>(2)</b>
        request.id(fruit.id);
        request.source(JsonObject.mapFrom(fruit).toString(), XContentType.JSON); <i class="conum" data-value="3"></i><b>(3)</b>
        restHighLevelClient.index(request, RequestOptions.DEFAULT); <i class="conum" data-value="4"></i><b>(4)</b>
    }

    public Fruit get(String id) throws IOException {
        GetRequest getRequest = new GetRequest("fruits", id);
        GetResponse getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
        if (getResponse.isExists()) {
            String sourceAsString = getResponse.getSourceAsString();
            JsonObject json = new JsonObject(sourceAsString); <i class="conum" data-value="5"></i><b>(5)</b>
            return json.mapTo(Fruit.class);
        }
        return null;
    }

    public List&lt;Fruit&gt; searchByColor(String color) throws IOException {
        return search("color", color);
    }

    public List&lt;Fruit&gt; searchByName(String name) throws IOException {
        return search("name", name);
    }

    private List&lt;Fruit&gt; search(String term, String match) throws IOException {
        SearchRequest searchRequest = new SearchRequest("fruits");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchQuery(term, match));
        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits hits = searchResponse.getHits();
        List&lt;Fruit&gt; results = new ArrayList&lt;&gt;(hits.getHits().length);
        for (SearchHit hit : hits.getHits()) {
            String sourceAsString = hit.getSourceAsString();
            JsonObject json = new JsonObject(sourceAsString);
            results.add(json.mapTo(Fruit.class));
        }
        return results;
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this example you can note the following:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>We inject an Elasticsearch <code>RestHighLevelClient</code> inside the service.</p>
</li>
<li>
<p>We create an Elasticsearch index request.</p>
</li>
<li>
<p>We use Vert.x <code>JsonObject</code> to serialize the object before sending it to Elasticsearch, you can use whatever you want to serialize to JSON.</p>
</li>
<li>
<p>We send the request to Elasticsearch.</p>
</li>
<li>
<p>In order to deserialize the object from Elasticsearch, we again use Vert.x <code>JsonObject</code>.</p>
</li>
</ol>
</div>
</div>
</div>
<div class="sect1">
<h2 id="hibernate-search-elasticsearch"><a class="anchor" href="#hibernate-search-elasticsearch"></a>Hibernate Search Elasticsearch</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Quarkus supports Hibernate Search with Elasticsearch via the <code>hibernate-search-elasticsearch</code> extension.</p>
</div>
<div class="paragraph">
<p>Hibernate Search Elasticsearch allows to synchronize your JPA entities to an Elasticsearch cluster and offers a way to query your Elasticsearch cluster using the Hibernate Search API.</p>
</div>
<div class="paragraph">
<p>If you&#8217;re interested in it, you can read the <a href="hibernate-search-elasticsearch">Hibernate Search with Elasticsearch guide</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="cluster-health-check"><a class="anchor" href="#cluster-health-check"></a>Cluster Health Check</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If you are using the <code>quarkus-smallrye-health</code> extension, both the extension will automatically add a readiness health check
to validate the health of the cluster.</p>
</div>
<div class="paragraph">
<p>So when you access the <code>/health/ready</code> endpoint of your application you will have information about the cluster status.
It uses the cluster health endpoint, the check will be down if the status of the cluster is <strong>red</strong>, or the cluster is not available.</p>
</div>
<div class="paragraph">
<p>This behavior can be disabled by setting the <code>quarkus.elasticsearch.health.enabled</code> property to <code>false</code> in your <code>application.properties</code>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="building-a-native-executable"><a class="anchor" href="#building-a-native-executable"></a>Building a native executable</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You can use both clients in a native executable.</p>
</div>
<div class="paragraph">
<p>You can build a native executable with the usual command <code>./mvnw package -Pnative</code>.</p>
</div>
<div class="paragraph">
<p>Running it is as simple as executing <code>./target/elasticsearch-low-level-client-quickstart-1.0-SNAPSHOT-runner</code>.</p>
</div>
<div class="paragraph">
<p>You can then point your browser to <code><a href="http://localhost:8080/fruits.html" class="bare">http://localhost:8080/fruits.html</a></code> and use your application.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="conclusion"><a class="anchor" href="#conclusion"></a>Conclusion</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Accessing an Elasticsearch cluster from a low level or a high level client is easy with Quarkus as it provides easy configuration, CDI integration and native support for it.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="configuration-reference"><a class="anchor" href="#configuration-reference"></a>Configuration Reference</h2>
<div class="sectionbody">
<div class="paragraph configuration-legend">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> Configuration property fixed at build time - All other configuration properties are overridable at runtime</p>
</div>
<table class="tableblock frame-all grid-all stretch configuration-reference searchable">
<colgroup>
<col style="width: 80%;">
<col style="width: 10%;">
<col style="width: 10%;">
</colgroup>
<tbody>
<tr>
<th class="tableblock halign-left valign-top"><p class="tableblock"><a id="quarkus-elasticsearch-restclient-lowlevel_configuration"></a><a href="#quarkus-elasticsearch-restclient-lowlevel_configuration">Configuration property</a></p></th>
<th class="tableblock halign-left valign-middle"><p class="tableblock">Type</p></th>
<th class="tableblock halign-left valign-middle"><p class="tableblock">Default</p></th>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> <a id="quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.health.enabled"></a><code><a href="#quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.health.enabled">quarkus.elasticsearch.health.enabled</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>Whether or not an health check is published in case the smallrye-health extension is present.</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">boolean</p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>true</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><a id="quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.hosts"></a><code><a href="#quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.hosts">quarkus.elasticsearch.hosts</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>The list of hosts of the Elasticsearch servers.</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">list of host:port</p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>localhost:9200</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><a id="quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.protocol"></a><code><a href="#quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.protocol">quarkus.elasticsearch.protocol</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>The protocol to use when contacting Elasticsearch servers. Set to "https" to enable SSL/TLS.</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>http</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><a id="quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.username"></a><code><a href="#quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.username">quarkus.elasticsearch.username</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>The username for basic HTTP authentication.</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-middle"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><a id="quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.password"></a><code><a href="#quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.password">quarkus.elasticsearch.password</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>The password for basic HTTP authentication.</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-middle"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><a id="quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.connection-timeout"></a><code><a href="#quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.connection-timeout">quarkus.elasticsearch.connection-timeout</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>The connection timeout.</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><a href="https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html">Duration</a>
  <a href="#duration-note-anchor" title="More information about the Duration format"><span class="icon"><i class="fa fa-question-circle"></i></span></a></p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>1S</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><a id="quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.socket-timeout"></a><code><a href="#quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.socket-timeout">quarkus.elasticsearch.socket-timeout</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>The socket timeout.</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><a href="https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html">Duration</a>
  <a href="#duration-note-anchor" title="More information about the Duration format"><span class="icon"><i class="fa fa-question-circle"></i></span></a></p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>30S</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><a id="quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.max-connections"></a><code><a href="#quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.max-connections">quarkus.elasticsearch.max-connections</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>The maximum number of connections to all the Elasticsearch servers.</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">int</p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>20</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><a id="quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.max-connections-per-route"></a><code><a href="#quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.max-connections-per-route">quarkus.elasticsearch.max-connections-per-route</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>The maximum number of connections per Elasticsearch server.</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">int</p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>10</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><a id="quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.io-thread-counts"></a><code><a href="#quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.io-thread-counts">quarkus.elasticsearch.io-thread-counts</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>The number of IO thread. By default, this is the number of locally detected processors.
 Thread counts higher than the number of processors should not be necessary because the I/O threads rely on non-blocking operations, but you may want to use a thread count lower than the number of processors.</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">int</p></td>
<td class="tableblock halign-left valign-middle"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><a id="quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.discovery.enabled"></a><code><a href="#quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.discovery.enabled">quarkus.elasticsearch.discovery.enabled</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>Defines if automatic discovery is enabled.</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">boolean</p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>false</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><a id="quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.discovery.refresh-interval"></a><code><a href="#quarkus-elasticsearch-restclient-lowlevel_quarkus.elasticsearch.discovery.refresh-interval">quarkus.elasticsearch.discovery.refresh-interval</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>Refresh interval of the node list.</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><a href="https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html">Duration</a>
  <a href="#duration-note-anchor" title="More information about the Duration format"><span class="icon"><i class="fa fa-question-circle"></i></span></a></p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>5M</code></p></td>
</tr>
</tbody>
</table>
<div id="duration-note-anchor" class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="title">About the Duration format</div>
<div class="paragraph">
<p>The format for durations uses the standard <code>java.time.Duration</code> format.
You can learn more about it in the <a href="https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html#parse-java.lang.CharSequence-">Duration#parse() javadoc</a>.</p>
</div>
<div class="paragraph">
<p>You can also provide duration values starting with a number.
In this case, if the value consists only of a number, the converter treats the value as seconds.
Otherwise, <code>PT</code> is implicitly prepended to the value to obtain a standard <code>java.time.Duration</code> format.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
